package com.molyfun.parents.service.music;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.wifi.WifiManager;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.molyfun.parents.MFPApplication;
import com.molyfun.parents.rest.bean.StringResponse;
import com.molyfun.parents.rest.bean.UploadUrlRequest;
import com.molyfun.parents.utils.UrlUtils;

import java.io.IOException;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by william(liuchao.hit@gmail.com).
 * Date:11/23/16.
 */
public class MusicPlayService extends Service implements IMusicFocusable, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {

    public static final String FLAG_MUSIC_URL = "music_url";

    // 第一次播放，需要传递数据源
    public static final String ACTION_PLAY = "com.molyfun.parents.action.PLAY";
    // 播放暂停
    public static final String ACTION_PAUSE = "com.molyfun.parents.action.PAUSE";
    // 停止播放
    public static final String ACTION_STOP = "com.molyfun.parents.action.STOP";
    // 播放暂停后恢复
    public static final String ACTION_RESUME = "com.molyfun.parents.action.RESUME";

    private static final String WIFI_LOCK_NAME = "wifi_lock";

    // 失去焦点，仍能播放音乐是，调小音量
    public static final float DUCK_VOLUME = 0.1f;

    MediaPlayer mPlayer = null;

    // 焦点管理类
//    AudioFocusHelper mAudioFocusHelper = null;

    // 播放器状态
    public static enum State {
        Stopped, Preparing, Playing, // 从头播放
        State, Paused
    }

    State mState = State.Stopped;

    // 失去焦点原因，用于重新获得焦点后播放音乐
    enum PauseReason {
        UserRequest, FocusLoss,
    }

    PauseReason mPauseReason = PauseReason.UserRequest;

    // 焦点的状态
//    enum AudioFocus {
//        NoFocus, Focused
//    }

//    AudioFocus mAudioFocus = AudioFocus.NoFocus;

    //缓存播放的音乐信息
    private String mMusicItem;

    private WifiManager.WifiLock mWifiLock;

//    //重启需要关闭音乐
//    private BroadcastReceiver mRestartReceiver = null;

//    //缓存Context引用
//    private Context mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mWifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
                .createWifiLock(WifiManager.WIFI_MODE_FULL, WIFI_LOCK_NAME);

//        if (android.os.Build.VERSION.SDK_INT >= 8) {
//            mAudioFocusHelper = new AudioFocusHelper(this,
//                    this);
//        } else {
//            mAudioFocus = AudioFocus.Focused;
//        }

    }

    void createMediaPlayerIfNeeded() {
        if (mPlayer == null) {
            mPlayer = new MediaPlayer();
//			mPlayer = new MediaPlayer(mContext);
            mPlayer.setWakeMode(this,
                    PowerManager.PARTIAL_WAKE_LOCK);
            mPlayer.setOnPreparedListener(this);
            mPlayer.setOnCompletionListener(this);
            mPlayer.setOnErrorListener(this);
        } else
            mPlayer.reset();
    }

    public boolean checkBeforeStart(Intent intent, int startId) {
        if (intent != null) {
            return true;
        }
        return false;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (checkBeforeStart(intent, startId)) {
            String action = intent.getAction();
            if (action.equals(ACTION_PLAY)) {
                String newMusicUrl = intent.getStringExtra(FLAG_MUSIC_URL);
                if (mState == State.Playing) {
                    processStopRequest();
                    if(!TextUtils.isEmpty(mMusicItem) && mMusicItem.equals(newMusicUrl)){
                        //如果是同一个旧什么都不做，相当去停止
                    }else{
                        mMusicItem = newMusicUrl;
                        if (!TextUtils.isEmpty(mMusicItem)) {

                            if(UrlUtils.isExpired(mMusicItem)){
                                UploadUrlRequest uploadUrlRequest = new UploadUrlRequest();
                                uploadUrlRequest.setUrl(UrlUtils.getNewUrl(mMusicItem));
                                Call<StringResponse> call = MFPApplication.getInstance().getRestClient().updateMediaUrl(uploadUrlRequest);
                                call.enqueue(new Callback<StringResponse>() {
                                    @Override
                                    public void onResponse(Call<StringResponse> call, Response<StringResponse> response) {
                                        mMusicItem = response.body().getData();
                                        processPlayRequest(mMusicItem);
                                    }

                                    @Override
                                    public void onFailure(Call<StringResponse> call, Throwable t) {
                                    }
                                });
                            }else{
                                processPlayRequest(mMusicItem);
                            }

                        }
                    }
                }else{
                    mMusicItem = newMusicUrl;
                    if (!TextUtils.isEmpty(mMusicItem)) {
                        processPlayRequest(mMusicItem);
                    }
                }

            } else if (action.equals(ACTION_PAUSE)) {
                processPauseRequest();
            } else if (action.equals(ACTION_STOP)) {
                processStopRequest();
            } else if (action.equals(ACTION_RESUME)) {
                processResumeRequest();
            }

        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void processPlayRequest(String url) {
        System.out.println("processPlayRequest--->" + url);
        if (!TextUtils.isEmpty(url)) {
//            tryToGetAudioFocus();
            playSong(url);
        }
    }

    private void processPauseRequest() {
        if (mPlayer != null) {
            mState = State.Paused;
            mPlayer.pause();
            relaxResources(false);
            mPauseReason = PauseReason.UserRequest;
            //目前没有暂停状态，发送停止状态出去
            MusicStatusCenter.notifyMusicStatusListener(mState, mMusicItem);
        }
    }

    private void processStopRequest() {
        if (mPlayer !=null && mState != State.Stopped) {
            mPlayer.setVolume(DUCK_VOLUME, DUCK_VOLUME);  // we'll be relatively quiet
            mState = State.Stopped;
            mPauseReason = PauseReason.UserRequest;
            relaxResources(true);
//            giveUpAudioFocus();
            MusicStatusCenter.notifyMusicStatusListener(mState, mMusicItem);
        }
    }

    private void processResumeRequest() {
        if (mPlayer != null && mState == State.Paused) {
//            tryToGetAudioFocus();
            mPlayer.start();
            mState = State.Playing;
            MusicStatusCenter.notifyMusicStatusListener(mState, mMusicItem);
        }
    }

    private void relaxResources(boolean releaseMediaPlayer) {

        if (releaseMediaPlayer && mPlayer != null) {
            mPlayer.reset();
            mPlayer.release();
            mPlayer = null;
        }
        if (mWifiLock.isHeld()) {
            mWifiLock.release();
        }
    }

//    private void giveUpAudioFocus() {
//        if (mAudioFocus == AudioFocus.Focused && mAudioFocusHelper != null
//                && mAudioFocusHelper.abandonFocus())
////        	if (mAudioFocus == AudioFocus.Focused)
//            mAudioFocus = AudioFocus.NoFocus;
//    }

    private void configAndStartMediaPlayer() {
//        if (mAudioFocus == AudioFocus.NoFocus) {
//            if (mPlayer.isPlaying()) {
//                mState = State.Paused;
//                mPlayer.pause();
//                relaxResources(false);
//                MusicStatusCenter.notifyMusicStatusListener(State.Paused, mMusicItem);
//            }
//            return;
//        }
        if (!mPlayer.isPlaying()) {
            mPlayer.start();
            mState = State.Playing;
            MusicStatusCenter.notifyMusicStatusListener(mState, mMusicItem);
        }

    }

//    private void tryToGetAudioFocus() {
////    	if (mAudioFocus != AudioFocus.Focused )
//        if (mAudioFocus != AudioFocus.Focused && mAudioFocusHelper != null
//                && mAudioFocusHelper.requestFocus())
//            mAudioFocus = AudioFocus.Focused;
//    }

    private void playSong(String manualUrl) {
        System.out.println("playSong--->" + manualUrl);
        mState = State.Stopped;
        relaxResources(false);

        try {
            if (manualUrl != null) {
                createMediaPlayerIfNeeded();
                mPlayer.setDataSource(manualUrl);

            }

            mState = State.Preparing;
            // Preparing状态增加回调，维护状态同步
            MusicStatusCenter.notifyMusicStatusListener(mState, mMusicItem);

            mPlayer.setVolume(1.0f, 1.0f); // we can be loud
            mPlayer.prepareAsync();


            if (!mWifiLock.isHeld()) {
                mWifiLock.acquire();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    //音乐播放完成
    @Override
    public void onCompletion(MediaPlayer player) {
        System.out.println("onCompletion--->player");
        processStopRequest();
    }

    @Override
    public void onPrepared(MediaPlayer player) {
        mState = State.Playing;
        configAndStartMediaPlayer();
//        //准备完成，开始播放音乐
//        MusicStatusCenter.notifyMusicStatusListener(mState, mMusicItem);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        System.out.println("onError--what-->" + what + "--extra-->" + extra);
        relaxResources(true);
//        processPlayRequest(mMusicItem);
        return true;
    }

    @Override
    public void onGainedAudioFocus() {
//        Toast.makeText(mContext, "gained audio focus.", Toast.LENGTH_SHORT).show();
//        mAudioFocus = AudioFocus.Focused;

        if (mState == State.Playing || (mState == State.Paused && mPauseReason == PauseReason.FocusLoss)) {
            processResumeRequest();
//        	configAndStartMediaPlayer();
        }
    }

    @Override
    public void onLostAudioFocus(boolean canDuck) {
//        Toast.makeText(mContext, "lost audio focus." + (canDuck ? "can duck" :
//            "no duck"), Toast.LENGTH_SHORT).show();
//        mAudioFocus = AudioFocus.NoFocus;
        if (mPlayer != null && mPlayer.isPlaying()) {
            mPauseReason = PauseReason.FocusLoss;
            if (mPlayer.isPlaying()) {
                mState = State.Paused;
                mPlayer.pause();
                relaxResources(false);
//                mPauseReason = PauseReason.UserRequest;
                MusicStatusCenter.notifyMusicStatusListener(State.Paused, mMusicItem);
            }
        }

    }

    @Override
    public void onDestroy() {
        mState = State.Stopped;
        relaxResources(true);
//        giveUpAudioFocus();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}
